package com.atguigu.springcloud.config;

import com.atguigu.springcloud.callback.RabbitMQConfirmCallback;
import com.atguigu.springcloud.callback.RabbitMQReturnCallback;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.ConfirmType;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;

@Configuration
public class RabbitMQ_Config {

	//主机地址
	@Value("${spring.rabbitmq.host}")
    private String host;

	//端口
    @Value("${spring.rabbitmq.port}")
    private int port;

    //用户名
    @Value("${spring.rabbitmq.username}")
    private String username;

    //密码
    @Value("${spring.rabbitmq.password}")
    private String password;

    //虚拟主机
    @Value("${spring.rabbitmq.virtual-host}")
    private String virtual_host;

    //响应超时时间
    @Value("${spring.rabbitmq.template.reply-timeout}")
    private long reply_timeout;

    //连接工厂-生产者
    @Bean
	@Primary
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtual_host);
        connectionFactory.setPublisherConfirmType(ConfirmType.CORRELATED);
        connectionFactory.setPublisherReturns(true);
        return connectionFactory;
    }

	//SIMPLE-RabbitTemplate
	@Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate simpleRabbitTemplate() {
        RabbitTemplate simpleRabbitTemplate = new RabbitTemplate(connectionFactory());
        simpleRabbitTemplate.setMandatory(true);
        simpleRabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return simpleRabbitTemplate;
    }

    //连接工厂-消费者
    @Bean
    public ConnectionFactory connectionFactory4Consumer() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtual_host);
        connectionFactory.setPublisherConfirmType(ConfirmType.CORRELATED);
        connectionFactory.setPublisherReturns(true);
        return connectionFactory;
    }

	//SIMPLE-SimpleRabbitListenerContainerFactory
	@Bean
	public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory() {
		SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory = new SimpleRabbitListenerContainerFactory();
		simpleRabbitListenerContainerFactory.setConnectionFactory(connectionFactory4Consumer());
		simpleRabbitListenerContainerFactory.setConcurrentConsumers(RabbitMQConst.SUND_SIMPLE_CONCURRENTCONSUMERS);
		simpleRabbitListenerContainerFactory.setMaxConcurrentConsumers(RabbitMQConst.SUND_SIMPLE_MAXCONCURRENTCONSUMERS);
		simpleRabbitListenerContainerFactory.setPrefetchCount(RabbitMQConst.SUND_PREFETCHCOUNT);
		simpleRabbitListenerContainerFactory.setMessageConverter(new Jackson2JsonMessageConverter());
		simpleRabbitListenerContainerFactory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
		return simpleRabbitListenerContainerFactory;
	}


    //RPC-RabbitTemplate
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rpcRabbitTemplate() {
        RabbitTemplate rpcRabbitTemplate = new RabbitTemplate(connectionFactory());
        rpcRabbitTemplate.setMandatory(true);
        rpcRabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rpcRabbitTemplate.setUserCorrelationId(true);
        rpcRabbitTemplate.setConfirmCallback(new RabbitMQConfirmCallback());
        rpcRabbitTemplate.setReturnCallback(new RabbitMQReturnCallback());
        //设置RPC响应超时时间
        rpcRabbitTemplate.setReplyTimeout(reply_timeout);
        return rpcRabbitTemplate;
    }
//
    //RPC-SimpleRabbitListenerContainerFactory
    @Bean
    public SimpleRabbitListenerContainerFactory rpcRabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory rpcRabbitListenerContainerFactory = new SimpleRabbitListenerContainerFactory();
        rpcRabbitListenerContainerFactory.setConnectionFactory(connectionFactory4Consumer());
        rpcRabbitListenerContainerFactory.setConcurrentConsumers(RabbitMQConst.SUND_RPC_CONCURRENTCONSUMERS);
        rpcRabbitListenerContainerFactory.setMaxConcurrentConsumers(RabbitMQConst.SUND_RPC_MAXCONCURRENTCONSUMERS);
        rpcRabbitListenerContainerFactory.setPrefetchCount(RabbitMQConst.SUND_PREFETCHCOUNT);
        rpcRabbitListenerContainerFactory.setMessageConverter(new Jackson2JsonMessageConverter());
        rpcRabbitListenerContainerFactory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return rpcRabbitListenerContainerFactory;
    }
}
